자기-어텐션

AI
gemma-4-31b
작성자
익명
작성일
2026.08.04
조회수
5
버전
v1

자기-어텐션 (Self-Attention)

1. 개요

자기-어텐션(Self-Attention)은 입력 시퀀스 내의 각 토큰이 동일한 시퀀스 내의 다른 모든 토큰과의 관계를 계산하여, 현재 토큰의 의미를 가장 잘 설명하는 문맥적 정보를 동적으로 추출하는 메커니즘이다. 이는 입력 데이터의 각 요소가 서로 어떤 연관성을 가지고 있는지를 파악함으로써, 문장 내의 장거리 의존성(Long-term Dependency) 문제를 효과적으로 해결하는 자연어 처리(NLP)의 핵심 기술이다.

2. 동작 원리

자기-어텐션은 입력된 각 토큰 벡터를 세 가지 서로 다른 역할의 벡터로 변환하여 연산을 수행한다.

2.1. 벡터 생성 (Query, Key, Value)

입력 벡터 $X$에 학습 가능한 파라미터인 가중치 행렬 $W^Q, W^K, W^V$를 곱하여 다음 세 가지 벡터를 생성한다. 모델은 학습 과정을 통해 어떤 정보를 추출하고 강조할지를 이 가중치 행렬들을 통해 스스로 결정한다.

  • Query (Q): 현재 시점에서 문맥을 파악하기 위해 질문을 던지는 벡터 (질의어)
  • Key (K): Query와 비교 대상이 되는 토큰들의 레이블 (색인)
  • Value (V): 각 토큰이 가지고 있는 실제 의미 정보 (값)

[Q, K, V 관계 도식] 입력 토큰 $\rightarrow$ (W^Q, W^K, W^V 곱) $\rightarrow$ (Q, K, V 생성) $\rightarrow$ (Q와 K의 유사도 계산) $\rightarrow$ (결과를 V에 적용) $\rightarrow$ 최종 문맥 벡터

2.2. 연산 단계

  1. 어텐션 스코어 계산: Query 벡터와 모든 Key 벡터 간의 내적(Dot-product)을 통해 유사도를 측정한다.
  2. 스케일링 및 소프트맥스: 계산된 스코어를 스케일링한 후, 소프트맥스(Softmax) 함수를 적용하여 합이 1이 되는 확률 분포(가중치)로 변환한다.
  3. 가중합 산출: 산출된 가중치를 각 Value 벡터에 곱하여 모두 더함으로써 최종 문맥 벡터를 도출한다.

[수식 표현] $$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$ (여기서 $d_k$는 Key 벡터의 차원 수이다.)

3. 스케일드 닷-프로덕트 어텐션 (Scaled Dot-Product Attention)

앞서 제시한 수식 $\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$에서 분모의 $\sqrt{d_k}$가 바로 스케일링 요소이다.

단순 내적을 사용할 경우, 벡터의 차원($d_k$)이 커질수록 내적 값의 절대값이 매우 커지는 경향이 있다. 이는 소프트맥스 함수의 입력값이 커짐에 따라 기울기(Gradient)가 매우 작은 영역으로 이동하게 만들어, 역전파 과정에서 그라디언트 소실(Gradient Vanishing) 문제를 야기한다.

이를 방지하기 위해 내적 결과값을 $\sqrt{d_k}$로 나누는 스케일링(Scaling) 기법을 도입한다. 이를 통해 값의 분산을 조절하여 학습의 안정성을 높이고 수렴 속도를 개선한다.

4. 멀티-헤드 어텐션 (Multi-Head Attention)

단일 어텐션 헤드만 사용할 경우, 모델은 한 번에 하나의 관계(예: 문법적 관계)에만 집중하는 경향이 있다. 멀티-헤드 어텐션은 여러 개의 어텐션 헤드를 병렬로 배치하여, 서로 다른 표현 공간(Representation Subspaces)에서 정보를 동시에 포착한다.

구분 단일 헤드 어텐션 (Single-Head) 멀티 헤드 어텐션 (Multi-Head)
관점 하나의 관점에서만 관계 파악 여러 관점(문법, 의미, 지칭 대상 등)에서 동시 파악
표현력 제한적임 풍부한 문맥적 표현 가능
연산 방식 한 번의 Q, K, V 연산 $h$개의 헤드로 나누어 병렬 연산 후 결합(Concat)
결과물 단일 문맥 벡터 각 헤드의 출력값을 연결(Concatenate)한 후, 최종 선형 층(Linear Layer, $W^O$)을 통과시켜 차원을 맞춘 종합 벡터

5. 마스킹 (Masking)

마스킹은 특정 토큰이 다른 토큰을 참조하지 못하도록 강제하는 기법이다. 주로 다음과 같은 상황에서 사용된다.

  • 패딩 마스크(Padding Mask): 입력 문장의 길이를 맞추기 위해 추가된 의미 없는 <PAD> 토큰이 어텐션 계산에 영향을 주지 않도록 $-\infty$로 처리하여 소프트맥스 결과값이 0이 되게 한다.
  • 룩-어헤드 마스크(Look-ahead Mask): 디코더(Decoder)에서 미래의 토큰을 미리 보고 예측하는 '치팅'을 방지하기 위해, 현재 시점 이후의 토큰들을 가리는 기법이다.

6. 시간 및 공간 복잡도 분석

자기-어텐션은 모든 토큰 쌍 간의 관계를 계산하므로 시퀀스 길이에 따라 복잡도가 급격히 증가한다.

  • 시간 복잡도: $O(n^2 \cdot d)$
  • $n$: 시퀀스 길이 (토큰 수)
  • $d$: 모델의 임베딩 차원($d_{model}$)
  • 모든 토큰 쌍($n \times n$)에 대해 내적 연산을 수행하므로 시퀀스 길이의 제곱에 비례한다.
  • 공간 복잡도: $O(n^2)$
  • $n \times n$ 크기의 어텐션 가중치 행렬(Attention Weight Matrix)을 저장해야 하므로 메모리 사용량이 제곱으로 증가한다.

7. 특징 및 장점

  1. 병렬 연산 가능: RNN과 달리 이전 시점의 계산 결과가 필요 없으므로, 전체 시퀀스를 한 번에 처리할 수 있어 GPU 연산 효율이 극대화된다.
  2. 전역 수용장 (Global Receptive Field): 토큰 간의 거리에 상관없이 단 한 번의 연산으로 직접 연결되므로, 매우 먼 거리의 토큰 간 관계도 손실 없이 파악할 수 있다.
  3. 동적 가중치: 입력 데이터에 따라 가중치가 실시간으로 결정되므로, 유연한 문맥 파악이 가능하다.

8. 활용 및 응용

자기-어텐션은 트랜스포머(Transformer) 아키텍처의 핵심 엔진이며, 이를 기반으로 현대의 LLM이 탄생했다. - BERT: 인코더 구조를 사용하여 양방향(Bidirectional) 문맥을 파악하는 데 활용. - GPT: 디코더 구조와 마스킹을 사용하여 다음 토큰을 예측하는 생성형 모델에 활용.

8.1. 어텐션 맵 시각화 예시

어텐션 맵은 $n \times n$ 행렬로 시각화되며, 특정 단어가 다른 단어에 얼마나 집중하고 있는지를 색상으로 표현한다. - 예: "The animal didn't cross the street because it was too tired"라는 문장에서 'it'이라는 토큰의 어텐션 맵을 확인하면, 'it'이 문맥상 'animal'을 지칭하고 있음을 나타내는 'animal' 토큰에 높은 가중치가 할당된 것을 확인할 수 있다.

8.2. 효율적 어텐션 기법 (Efficient Attention)

$O(n^2)$의 복잡도로 인해 입력 시퀀스가 길어질수록 연산 비용이 기하급수적으로 증가하는 문제를 해결하기 위해 다양한 최적화 기법이 연구되고 있다. - Sparse Attention: 모든 토큰 쌍을 계산하는 대신, 특정 패턴(예: 주변 토큰이나 고정 간격 토큰)만 계산하여 복잡도를 줄이는 방식이다. - Linear Attention: 커널 함수 등을 이용하여 연산 순서를 변경함으로써 복잡도를 $O(n)$ 수준으로 낮추는 기법이다. - FlashAttention: GPU 메모리 계층 구조를 최적화하여 IO 오버헤드를 줄임으로써 실제 연산 속도와 메모리 효율을 획기적으로 개선한 기법이다.

8.3. PyTorch 기반 간단 구현 예제

import torch
import torch.nn as nn
import torch.nn.functional as F

class SimpleSelfAttention(nn.Module):
    def __init__(self, d_model):
        super().__init__()
        self.d_model = d_model
        # Q, K, V를 위한 선형 층 (학습 가능한 파라미터)
        self.w_q = nn.Linear(d_model, d_model)
        self.w_k = nn.Linear(d_model, d_model)
        self.w_v = nn.Linear(d_model, d_model)

    def forward(self, x):
        # x shape: (batch_size, seq_len, d_model)
        q = self.w_q(x)
        k = self.w_k(x)
        v = self.w_v(x)

        # 1. 어텐션 스코어 계산 (Dot-product)
        # (batch, seq_len, d_model) @ (batch, d_model, seq_len) -> (batch, seq_len, seq_len)
        attn_scores = torch.matmul(q, k.transpose(-2, -1)) 
        
        # 2. 스케일링 및 소프트맥스
        attn_scores = attn_scores / (self.d_model ** 0.5)
        attn_weights = F.softmax(attn_scores, dim=-1)

        # 3. 가중합 산출
        # (batch, seq_len, seq_len) @ (batch, seq_len, d_model) -> (batch, seq_len, d_model)
        output = torch.matmul(attn_weights, v)
        return output, attn_weights

AI 생성 콘텐츠 안내

이 문서는 AI 모델(gemma-4-31b)에 의해 생성된 콘텐츠입니다.

주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.

이 AI 생성 콘텐츠가 도움이 되었나요?